// 组合模式
// 思想：将对象组合成树形结构以表示“部分-整体”的层次结构，组合模式使得用户对单个对象和组合对象的使用具有一致性。
/*
角色：
（1）子对象
（2）组合对象
（3）抽象类：主要定义了参与组合的对象的公共接口，也可以直接在组合对象中定义 （JS因为是动态语言一般不做实现）

组合模式统一对待树中的所有对象，忽略组合对象和叶对象的区别
客户在面对这棵树的时候，不用关心当前正在处理的对象是组合对象还是叶对象
它们的区别只有在运行时才会提现出来
*/

// 文件夹类
function Folder(name) {
  this.name = name
  this.files = []
  this.parent = null
}
Folder.prototype.add = function (file) {
  this.files.push(file)
  file.parent = this
}
Folder.prototype.scan = function () {
  console.log('开始扫描文件夹：', this.name)
  this.files.forEach(file => file.scan())
}

// 文件
function File(name) {
  this.name = name
  this.parent = null
}
File.prototype.scan = function () {
  console.log('开始扫描文件：', this.name)
}

const root = new Folder('root')
const books = new Folder('books')
const movies = new Folder('movies')
const file1 = new File('电子书')
const file2 = new File('波多野结衣')
const file3 = new File('小泽玛利亚')
const file4 = new File('梦幻西游')
books.add(file1)
movies.add(file2)
movies.add(file3)
root.add(file4)
root.add(books)
root.add(movies)

root.scan()